/*******************************************************************************
 * Copyright (c) 2011 Olexandr V. Shaposhnikov.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Olexandr V. Shaposhnikov - initial API and implementation and/or initial documentation
 *******************************************************************************/
package com.funkyroach.use.ui.text;

import java.io.Reader;
import java.io.StringReader;

import org.eclipse.core.resources.IResource;
import org.eclipse.dltk.core.IMember;
import org.eclipse.dltk.core.IModelElement;
import org.eclipse.dltk.core.ISourceModule;
import org.eclipse.dltk.core.ISourceRange;
import org.eclipse.dltk.core.ModelException;
import org.eclipse.dltk.internal.core.SourceField;
import org.eclipse.dltk.internal.core.SourceMethod;
import org.eclipse.dltk.internal.core.SourceModule;
import org.eclipse.dltk.internal.core.SourceType;
import org.eclipse.dltk.internal.core.SourceTypeElementInfo;
import org.eclipse.dltk.ui.documentation.IScriptDocumentationProvider;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Document;

import com.funkyroach.use.core.codeassist.USAssistParser;
import com.funkyroach.use.core.mixin.USMixinModel;

public class USDocProvider implements IScriptDocumentationProvider {

    private USMixinModel mixinModel;
    private USAssistParser parser = new USAssistParser();

    @Override
    public Reader getInfo(String content) {
        return new StringReader(content);
    }

    @Override
    public Reader getInfo(IMember element, boolean lookIntoParents, boolean lookIntoExternal) {
        mixinModel = USMixinModel.instance(element.getScriptProject());
        ISourceModule sourceModule = element.getSourceModule();
        try {

            // USModuleDeclaration moduleDeclaration = (USModuleDeclaration)
            // this.parser.parse();
            IResource res = element.getUnderlyingResource();
            System.out.println(res);
        } catch (ModelException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        if (element instanceof SourceType) {
            SourceType classType = (SourceType) element;
            try {
                //SourceTypeElementInfo elementInfo = (SourceTypeElementInfo) classType.getElementInfo();
                ISourceRange range = classType.getSourceRange();
                String help = classType.getSourceModule().getSource();
                IModelElement parent = classType.getParent();
                int rangeStart = range.getOffset();
                if (parent != null && parent instanceof SourceModule) {
                    rangeStart = 0;
                }

                help = help.substring(rangeStart, range.getOffset() + range.getLength());

                help = convertToHTML(help);
                return new StringReader(help);
            } catch (ModelException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        } else if (element instanceof SourceField) {
            SourceField field = (SourceField) element;
            try {
                // SourceTypeElementInfo elementInfo = (SourceTypeElementInfo)
                // classType.getElementInfo();
                ISourceRange range = field.getSourceRange();
                String help = field.getSourceModule().getSource();
                help = help.substring(range.getOffset(), range.getOffset() + range.getLength());

                help = convertToHTML(help);
                return new StringReader(help);
            } catch (ModelException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        } else if (element instanceof SourceMethod) {
            SourceMethod method = (SourceMethod) element;
            try {
                // SourceTypeElementInfo elementInfo = (SourceTypeElementInfo)
                // classType.getElementInfo();
                ISourceRange range = method.getSourceRange();
                String help = method.getSourceModule().getSource();
                help = help.substring(range.getOffset(), range.getOffset() + range.getLength());

                help = convertToHTML(help);
                return new StringReader(help);
            } catch (ModelException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        element.getScriptProject();
        return new StringReader(element.getElementName() + " help");
    }

    protected String getLine(Document d, int line) throws BadLocationException {
        return d.get(d.getLineOffset(line), d.getLineLength(line));
    }

    protected String convertToHTML(String header) {
        StringBuffer result = new StringBuffer();
        // result.append("<p>\n");
        Document d = new Document(header);
        for (int line = 0;; line++) {
            try {
                String str = getLine(d, line).trim();
                if (str == null)
                    break;
                while (str.length() > 0 && str.startsWith("#"))
                    str = str.substring(1);
                while (str.length() > 0 && str.endsWith("#"))
                    str = str.substring(0, str.length() - 1);
                if (str.length() == 0)
                    result.append("<p>");
                else {
                    if (str.trim().matches("\\w*:")) {
                        result.append("<h4>");
                        result.append(str);
                        result.append("</h4>");
                    } else
                        result.append(str + "<br>");
                }
            } catch (BadLocationException e) {
                break;
            }

        }
        return result.toString();
    }
}